mini.DataGrid.prototype.getRowGroupByValue = function (value) {
    var groups = this.getGroupingView();
    for (var i = 0, l = groups.length; i < l; i++) {
        var g = groups[i];
        if (g.value == value) return g;
    }
    return null;
}
mini.Report = function (dg, title, topleft, topright, direction) {
    this.title = title;
    this.topleft = topleft || "&nbsp";
    this.topright = topright || "&nbsp";
    this.direction = direction || "portrait";
    /**
     * @type{mini.DataGrid}
    */
    this.dg = dg;
    this.ifrm = this._createIframe();
    this.tmpdiv = document.createElement("div");
}

mini.Report.prototype = {
    getvalue: null,
    _appendto: function (to, from) {
        while (from.firstChild) {
            to.appendChild(from.firstChild);
        }
    },
    _createIframe: function () {
        /**
        * @type{HTMLIFrameElement}
       */
        var ifrm = document.createElement('IFRAME');
        var doc = null;
        ifrm.setAttribute('style', 'visibility:hidden;width:100%;height:100%;position:absolute;left:0px;top:0px;');
        document.body.appendChild(ifrm);
        doc = ifrm.contentWindow.document;
        doc.write(`<link rel="stylesheet" href="/common/miniui/themes/report_${this.direction}.css"><body></body>`);


        var bdy = doc.body;
        doc.close();
        return { "iframe": ifrm, "body": bdy, "win": ifrm.contentWindow };
    },
    _createTitle: function () {
        let s;
        s = "<p class='Title'>" + this.title + "</p>";
        s += "<p class='top'>" + this.topleft + "<span class='right'>" + this.topright + "</span></p>";
        return s;
    },
    _createTableHeader: function () {
        var sb = '<table><tr style="display:none;height:0px">';
        /**
         * @type{Array}
        */
        var visibleColumns = this.dg.getVisibleColumns();
        visibleColumns.forEach(function (column) {
            if (column.type && (column.type == "indexcolumn" || column.type == "checkcolum")) return;
            sb += '<td style="';
            if (column.width) sb += 'width:' + column.width + ";";
            if (column.minWidth) sb += 'min-width:' + column.minWidth + "px;";
            sb += '" ></td>';
        })
        sb += "</tr>";


        var rows = this.dg.getVisibleColumnsRow();
        rows.forEach(function (columns) {
            sb += "<TR>";
            columns.forEach(function (column) {
                if (column.type && (column.type == "indexcolumn" || column.type == "checkcolum")) return;
                let headerText = (typeof column.header == "function") ? column.header.call(this.dg, column) : column.header || "&nbsp;";
                sb += '<td';
                if (column.rowspan) sb += ' rowspan="' + column.rowspan + '"';
                if (column.colspan) sb += ' colspan="' + column.colspan + '"';
                sb += ">" + headerText + "</td>";
            })
            sb += '</tr>'
        })
        return sb;
    },
    _OnDrawCell: function (record, column) {
        var value = record[column.field];
        let cellHtml;
        if (this.getvalue) cellHtml = this.getvalue(value, column);

        if (cellHtml) return cellHtml;

        cellHtml = value;
        var dateFormat = column.dateFormat || (column.dataType == "date" ? this.defaultColumnDateFormat : "");
        if (dateFormat) {
            if (mini.isDate(value)) {
                cellHtml = mini.formatDate(value, dateFormat);
            }
            else cellHtml = value;
        }
        if (column.dataType == "float") {
            var value = parseFloat(value);
            if (!isNaN(value)) {
                decimalPlaces = parseInt(column.decimalPlaces);
                if (isNaN(decimalPlaces)) decimalPlaces = 2;
                cellHtml = value.toFixed(decimalPlaces);
            }
        }
        if (column.dataType == "currency") {
            cellHtml = mini.formatCurrency(value, column.currencyUnit);
        }
        if (column.displayField) {
            cellHtml = mini._getMap(column.displayField, record);
        }
        if (column.numberFormat) {
            var number = parseFloat(cellHtml);
            if (!isNaN(number)) {
                cellHtml = mini.formatNumber(number, column.numberFormat);
            }
        }
        if (column.type == 'checkboxcolumn') {
            cellHtml = '<input type="checkbox" ' + (value == "1" || value == "true" ? "checked" : "unchecked") + "/>";
        }
        if (cellHtml && !!cellHtml.unshift && cellHtml.length == 0) {
            cellHtml = "&nbsp;";
        }
        if (cellHtml === null || cellHtml === undefined || cellHtml === "") cellHtml = "&nbsp;";
        return cellHtml;
    },
    _createRows: function () {

        let firstpage = true;
        let data = this.dg.getVisibleRows();
        let s = "";
        function getCapacity(firstpage, headCount, pager) {
            let height = pager.offsetHeight;
            let headerHeight = headCount * 30;
            let offset = 0;
            if (firstpage) {
                s = this._createTitle();
                this.tmpdiv.innerHTML = s;
                this._appendto(pager, this.tmpdiv);
                offset = pager.lastChild.offsetHeight + pager.lastChild.offsetTop
            }
            let rowHeight = height - headerHeight - offset - 16;
            return Math.floor(rowHeight / 30);
        }
        let visibleColumns = this.dg.getVisibleColumns();
        let headCount = this.dg.getVisibleColumnsRow().length;

        s = this._createTableHeader();
        let self = this;
        let pagecnt = 0;
        let rowspan = 0;
        let capacity = 0;
        let pager = null;
        data.forEach(function (row, idx) {
            if (capacity == 0) {
                /**
                * @type{HTMLDivElement}
                */
                pager = self._createPage();
                capacity = getCapacity.call(self, firstpage, headCount, pager);
                firstpage = false;
                pagecnt += 1;
                s = self._createTableHeader();
            }
            s += '<tr>';
            visibleColumns.forEach(function (column) {
                if (column.type && (column.type == "indexcolumn" || column.type == "checkcolum")) return;
                let cellHtml = self._OnDrawCell(row, column);
                if (column.renderer) {
                    if (typeof column.renderer == "function") {
                        cellHtml = column.renderer.call(column, {value:cellHtml});
                    } else {
                        cellHtml = eval(column.renderer + "({value:'" + cellHtml + "'})");
                    }
                }
                if (typeof cellHtml == 'string' || typeof cellHtml == 'number')
                    s += '<td>' + cellHtml + '</td>'
                else {
                    rowspan += 1;
                    if (rowspan == 1)
                        s += '<td rowspan =' + cellHtml.rowspan + '>' + cellHtml.text + '</td>'
                    else {
                        if (rowspan < cellHtml.rowspan)
                            return
                        else
                            rowspan = 0;
                    }
                }
            })
            s += '</tr>';
            capacity -= 1;
            if (capacity == 0) {
                s += '</table><p class="pagecnt">第&nbsp' + pagecnt + "&nbsp页</p>";
                self.tmpdiv.innerHTML = s;
                self._appendto(pager, self.tmpdiv);
            }
        })
        if (capacity != 0) {
            s += '</table><p class="pagecnt">第&nbsp' + pagecnt + "&nbsp页</p>";
            this.tmpdiv.innerHTML = s;
            this._appendto(pager, this.tmpdiv);
        }
    },
    _createPage: function () {
        let s = '<div class="content"></div><div class="newpage"></div>';
        this.tmpdiv.innerHTML = s;
        let result = this.tmpdiv.children[0];
        this._appendto(this.ifrm.body, this.tmpdiv);
        return result;
    },
    print: function () {
        this.ifrm.body.innerHTML = '';
        this._createRows();
        /**
         * @type{Window}
         */
        let win = this.ifrm.win;
        if (mini.isIE11)
            win.document.execCommand('print', false, null)
        else
            win.print();

    }
};
